#ifndef MDTX_USE_RCPPARMADILLO
#define MDTX_USE_RCPPARMADILLO
#endif

#include <RcppArmadillo.h>
using namespace Rcpp;

#include "mdtx-online/aggregator/aggregator_type_time.h"
using namespace mdtx::online;

#include "aggr_common.h"

using tumbling_ohlcv_ = aggr<true,
                             aggregator::tumbling_ohlcv<double, double, double>,
                             NumericVector,
                             NumericVector>;

//' Aggregate market orders to OHLCV tumbling window
//'
//' @param time POSIXct/Numeric/ITime vector Time
//' @param price Numeric vector Price
//' @param volume Numeric vector Volume
//' @param turnover Numeric vector Turnover
//' @param window_size Window size in seconds
//' @param align_window Whether to align window
//' @return List of time (ending time of bin), open, high, low, close, volume, turnover, vwap
//' @export
// [[Rcpp::export(rng = false)]]
List tumbling_ohlcv(NumericVector time, NumericVector price, NumericVector volume, NumericVector turnover,
                    double window_size, bool align_window = true)
{
    auto c = tumbling_ohlcv_::create(window_size, 0., align_window);
    return tumbling_ohlcv_::run_ohlcv7(c, time, price, volume, turnover);
}

// [[Rcpp::export(rng = false)]]
SEXP tumbling_ohlcv_new(double window_size, bool align_window = true)
{
    return tumbling_ohlcv_::create(window_size, 0., align_window);
}

// [[Rcpp::export(rng = false)]]
List tumbling_ohlcv_run(SEXP ptr, NumericVector time, NumericVector price, NumericVector volume, NumericVector turnover)
{
    return tumbling_ohlcv_::run_ohlcv7(ptr, time, price, volume, turnover);
}

using tumbling_vwap_ = aggr<true,
                            aggregator::tumbling_vwap<double, double, double>,
                            NumericVector,
                            NumericVector>;

//' Aggregate market orders to tumbling window, vwap only
//'
//' @param time POSIXct/Numeric/ITime vector Time
//' @param price Numeric vector Price
//' @param volume Numeric vector Volume
//' @param turnover Numeric vector Turnover
//' @param window_size Window size in seconds
//' @param align_window Whether to align window
//' @return List of time (ending time of bin), vwap, volume
//' @export
// [[Rcpp::export(rng = false)]]
List tumbling_vwap(NumericVector time, NumericVector price, NumericVector volume, NumericVector turnover,
                   double window_size, bool align_window = true)
{
    auto c = tumbling_vwap_::create(window_size, 0., align_window);
    return tumbling_vwap_::run_ohlcv3(c, time, price, volume, turnover);
}

// [[Rcpp::export(rng = false)]]
SEXP tumbling_vwap_new(double window_size, bool align_window = true)
{
    return tumbling_vwap_::create(window_size, 0., align_window);
}

// [[Rcpp::export(rng = false)]]
List tumbling_vwap_run(SEXP ptr, NumericVector time, NumericVector price, NumericVector volume, NumericVector turnover)
{
    return tumbling_vwap_::run_ohlcv3(ptr, time, price, volume, turnover);
}

using sliding_ohlcv_ = aggr<true,
                            aggregator::sliding_ohlcv<double, double, double>,
                            NumericVector,
                            NumericVector>;

//' Aggregate market orders to OHLCV sliding window
//'
//' @param time POSIXct/Numeric/ITime vector Time
//' @param price Numeric vector Price
//' @param volume Numeric vector Volume
//' @param turnover Numeric vector Turnover
//' @param window_size Window size in seconds
//' @return List of time (ending time of bin), open, high, low, close, volume, turnover, vwap
//' @export
// [[Rcpp::export(rng = false)]]
List sliding_ohlcv(NumericVector time, NumericVector price, NumericVector volume, NumericVector turnover,
                   double window_size)
{
    auto c = sliding_ohlcv_::create(window_size);
    return sliding_ohlcv_::run_ohlcv7(c, time, price, volume, turnover);
}

// [[Rcpp::export(rng = false)]]
SEXP sliding_ohlcv_new(double window_size)
{
    return sliding_ohlcv_::create(window_size);
}

// [[Rcpp::export(rng = false)]]
List sliding_ohlcv_run(SEXP ptr, NumericVector time, NumericVector price, NumericVector volume, NumericVector turnover)
{
    return sliding_ohlcv_::run_ohlcv7(ptr, time, price, volume, turnover);
}

using sliding_vwap_ = aggr<true,
                           aggregator::sliding_vwap<double, double, double>,
                           NumericVector,
                           NumericVector>;

//' Aggregate market orders to sliding window, vwap only
//'
//' @param time POSIXct/Numeric/ITime vector Time
//' @param price Numeric vector Price
//' @param volume Numeric vector Volume
//' @param turnover Numeric vector Turnover
//' @param window_size Window size in seconds
//' @return List of time (ending time of bin), vwap, volume
//' @export
// [[Rcpp::export(rng = false)]]
List sliding_vwap(NumericVector time, NumericVector price, NumericVector volume, NumericVector turnover,
                  double window_size)
{
    auto c = sliding_vwap_::create(window_size);
    return sliding_vwap_::run_ohlcv3(c, time, price, volume, turnover);
}

// [[Rcpp::export(rng = false)]]
SEXP sliding_vwap_new(double window_size)
{
    return sliding_vwap_::create(window_size);
}

// [[Rcpp::export(rng = false)]]
List sliding_vwap_run(SEXP ptr, NumericVector time, NumericVector price, NumericVector volume, NumericVector turnover)
{
    return sliding_vwap_::run_ohlcv3(ptr, time, price, volume, turnover);
}
